package com.bby.screentool.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.bby.screentool.bean.Action;
import com.bby.screentool.config.Context;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

@Slf4j
@Component
@ServerEndpoint("/websocket/{screenId}")
public class MWebSocket {
    //与某个客户端的连接会话，需要通过它来给客户端发送数据
    @Getter
    private Session session;
    /**
     * 用户ID
     */
    @Getter
    private String screenId;


    @Setter@Getter
    private boolean record = false;
    /**
     * 链接成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam(value = "screenId") String screenId) {
        log.debug(screenId + "连接");
        if (ObjectUtil.isEmpty(screenId) || !Context.idCache.containsKey(screenId)) {
            try {
                session.close();
                return;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        Context.addWebSocket(screenId, this);
        this.session = session;
        this.screenId = screenId;
    }

    /**
     * 链接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        Context.removeWebSocket(screenId);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message
     */
    @OnMessage
    public void onMessage(String message) {
        log.debug("【websocket消息】收到客户端消息:" + message);
        Action action = JSONUtil.toBean(message, Action.class);
        if (ObjectUtil.isEmpty(action)) {
            return;
        }
        if (Action.RECORD_READY.equals(action.getAction())){
            setRecord(true);
            return;
        }
        String targetId = action.getTargetId();
        MWebSocket target = Context.getSocketServer(targetId);
        if (target == null) {
            sendMessage(new Action(Action.ERROR, screenId, "目标id不存在！"));
            return;
        }
        target.sendMessage(action);

    }

    private void sendMessage(Action action) {
        sendMessage(JSONUtil.toJsonStr(action));
    }

    /**
     * 发送错误时的处理
     *
     * @param error
     */
    @OnError
    public void onError(Throwable error) {
        log.debug("用户错误,原因:" + error.getMessage());
        Context.removeWebSocket(screenId);
        error.printStackTrace();
    }

    // 此为广播消息
    public void sendAllMessage(String message) {
        log.debug("【websocket消息】广播消息:" + message);
        for (MWebSocket webSocket : Context.webSockets.values()) {
            try {
                if (webSocket.session.isOpen()) {
                    webSocket.session.getAsyncRemote().sendText(message);
                }
            } catch (Exception e) {
            }
        }
    }

    // 此为单点消息
    public void sendMessage(String message) {
        if (session != null && session.isOpen()) {
            try {
                session.getAsyncRemote().sendText(message);
            } catch (Exception e) {
            }
        }
    }

    // 此为单点消息(多人)
    public void sendMoreMessage(String[] screenIds, String message) {
        for (String screenId : screenIds) {
            MWebSocket server = Context.getSocketServer(screenId);
            if (server != null && server.session.isOpen()) {
                try {
                    log.debug("【websocket消息】 单点消息:" + message);
                    server.session.getAsyncRemote().sendText(message);
                } catch (Exception e) {
                }
            }
        }

    }
}
